<template>
  <div class="text2img-container">
    <el-row :gutter="20">
      <!-- 左侧生成面板 -->
      <el-col :xs="24" :sm="24" :md="12" :lg="8" :xl="8">
        <el-card class="generation-panel">
          <template #header>
            <div class="card-header">
              <span>文本生成图像</span>
              <div class="service-status">
                <el-tag v-if="serviceStatus" type="success" size="small">服务在线</el-tag>
                <el-tag v-else type="danger" size="small">服务离线</el-tag>
                <el-button :icon="Refresh" circle size="small" @click="checkService" :loading="checkingStatus"></el-button>
              </div>
            </div>
          </template>

          <el-form :model="generationForm" ref="generationFormRef" :rules="rules" label-position="top">
            <!-- 提示词 -->
            <el-form-item label="提示词" prop="prompt">
              <el-input 
                v-model="generationForm.prompt" 
                type="textarea" 
                :rows="4" 
                placeholder="输入提示词描述你想要生成的图像"
              ></el-input>
            </el-form-item>

            <!-- 负面提示词 -->
            <el-form-item label="负面提示词">
              <el-input 
                v-model="generationForm.negativePrompt" 
                type="textarea" 
                :rows="2" 
                placeholder="描述你不希望在图像中出现的内容（可选）"
              ></el-input>
            </el-form-item>

            <!-- 模型选择 -->
            <el-form-item label="模型" prop="modelName">
              <el-select 
                v-model="generationForm.modelName" 
                placeholder="选择模型" 
                style="width: 100%"
                @change="onModelChange"
                :loading="loadingModels"
              >
                <el-option 
                  v-for="model in models" 
                  :key="model.modelName" 
                  :label="model.displayName" 
                  :value="model.modelName"
                >
                  <div class="model-option">
                    <span>{{ model.displayName }}</span>
                    <el-tag v-if="model.isDefault" size="small" type="success">默认</el-tag>
                  </div>
                </el-option>
              </el-select>
            </el-form-item>

            <!-- 尺寸选择 -->
            <el-form-item label="尺寸">
              <el-row :gutter="10">
                <el-col :span="12">
                  <el-input-number 
                    v-model="generationForm.width" 
                    :min="256" 
                    :max="1024" 
                    :step="64" 
                    style="width: 100%"
                    placeholder="宽度"
                  ></el-input-number>
                </el-col>
                <el-col :span="12">
                  <el-input-number 
                    v-model="generationForm.height" 
                    :min="256" 
                    :max="1024" 
                    :step="64" 
                    style="width: 100%"
                    placeholder="高度"
                  ></el-input-number>
                </el-col>
              </el-row>
              <div class="preset-sizes">
                <el-button type="text" @click="setSize(512, 512)">512×512</el-button>
                <el-button type="text" @click="setSize(768, 512)">768×512</el-button>
                <el-button type="text" @click="setSize(512, 768)">512×768</el-button>
                <el-button type="text" @click="setSize(1024, 576)">1024×576</el-button>
              </div>
            </el-form-item>

            <!-- 高级选项 -->
            <el-collapse>
              <el-collapse-item title="高级选项">
                <el-form-item label="采样步数">
                  <el-slider 
                    v-model="generationForm.steps" 
                    :min="10" 
                    :max="150" 
                    :step="5" 
                    show-input
                  ></el-slider>
                </el-form-item>
                
                <el-form-item label="CFG缩放">
                  <el-slider 
                    v-model="generationForm.cfgScale" 
                    :min="1" 
                    :max="20" 
                    :step="0.5" 
                    show-input
                  ></el-slider>
                </el-form-item>
                
                <el-form-item label="种子值">
                  <el-input-number 
                    v-model="generationForm.seed" 
                    :min="-1" 
                    :max="2147483647" 
                    controls-position="right"
                    style="width: 100%"
                  ></el-input-number>
                  <div class="seed-options">
                    <el-button type="text" @click="generationForm.seed = -1">随机</el-button>
                    <el-button type="text" @click="generationForm.seed = Math.floor(Math.random() * 2147483647)">生成随机种子</el-button>
                  </div>
                </el-form-item>
              </el-collapse-item>
            </el-collapse>

            <!-- 提交按钮 -->
            <el-form-item>
              <el-button 
                type="primary" 
                @click="submitForm" 
                :loading="generating" 
                :disabled="!serviceStatus"
                style="width: 100%"
              >
                生成图像
              </el-button>
            </el-form-item>
          </el-form>
        </el-card>
      </el-col>

      <!-- 右侧预览区域 -->
      <el-col :xs="24" :sm="24" :md="12" :lg="16" :xl="16">
        <el-card class="preview-card">
          <template #header>
            <div class="card-header">
              <span>生成结果</span>
              <div v-if="generationResult">
                <el-tag :type="statusTypeMap[generationResult.status]">{{ statusTextMap[generationResult.status] }}</el-tag>
              </div>
            </div>
          </template>

          <div class="preview-container" v-loading="generating">
            <div v-if="generationResult && getImageUrl(generationResult)" class="image-container">
              <el-image 
                :src="getImageUrl(generationResult)" 
                fit="contain"
                :preview-src-list="[getImageUrl(generationResult)]"
                class="result-image"
              ></el-image>
              
              <div class="image-info">
                <p>
                  <b>任务ID:</b> {{ generationResult.taskId }}
                </p>
                <p>
                  <b>模型:</b> {{ generationResult.modelName }}
                </p>
                <p>
                  <b>尺寸:</b> {{ generationResult.width }}×{{ generationResult.height }}
                </p>
                <p v-if="generationResult.steps">
                  <b>步数:</b> {{ generationResult.steps }}
                </p>
                <p v-if="generationResult.cfgScale">
                  <b>CFG:</b> {{ generationResult.cfgScale }}
                </p>
                <p v-if="generationResult.samplerName">
                  <b>采样器:</b> {{ generationResult.samplerName }}
                </p>
                <p v-if="generationResult.seed !== undefined && generationResult.seed !== null">
                  <b>种子:</b> {{ generationResult.seed }}
                </p>
                <p v-if="generationResult.generationTime">
                  <b>生成耗时:</b> {{ (generationResult.generationTime / 1000).toFixed(2) }}秒
                </p>
                <p>
                  <b>创建时间:</b> {{ formatDateTime(generationResult.createTime) }}
                </p>
              </div>

              <div class="image-actions">
                <el-button type="primary" @click="downloadImage" :disabled="!getImageUrl(generationResult)">
                  <el-icon><Download /></el-icon> 下载图像
                </el-button>
                <el-button @click="regenerateWithSameParams">
                  <el-icon><RefreshRight /></el-icon> 重新生成
                </el-button>
              </div>
            </div>

            <div v-else-if="generating" class="placeholder">
              <p>正在生成图像，请稍候...</p>
            </div>
            
            <div v-else-if="generationResult && generationResult.status === 'failed'" class="error-container">
              <el-alert
                title="生成失败"
                type="error"
                description="图像生成失败，请检查参数后重试。"
                show-icon
              ></el-alert>
              <p v-if="generationResult.errorMessage" class="error-message">
                错误信息: {{ generationResult.errorMessage }}
              </p>
            </div>

            <div v-else class="placeholder">
              <div class="empty-image-large">
                <el-icon :size="48"><Picture /></el-icon>
                <p>暂无生成结果</p>
              </div>
              <p>填写左侧表单并点击"生成图像"按钮开始生成</p>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 模型配置展示 -->
    <div class="full-width-section">
      <ModelConfigView 
        :models="models" 
        @select-model="useModelConfig" 
      />
    </div>

    <!-- 历史记录组件 -->
    <div class="full-width-section">
      <Text2ImgHistory 
        :models="models" 
        :generating="generating" 
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { 
  Refresh, 
  RefreshRight, 
  Download,
  Picture
} from '@element-plus/icons-vue'
import { 
  generateImage, 
  checkServiceHealth, 
  getRecordByTaskId,
  type Txt2ImgRequest,
  type Txt2ImgResponse,
  type ModelConfig
} from '@/api/text2img'
import { getText2ImgModels } from '@/api/modelConfig'

// 导入子组件
import Text2ImgHistory from './Text2ImgHistory.vue'
import ModelConfigView from './ModelConfigView.vue'

// 服务状态
const serviceStatus = ref(false)
const checkingStatus = ref(false)

// 表单数据
const generationForm = reactive<Txt2ImgRequest>({
  prompt: '',
  negativePrompt: '',
  modelName: '',
  width: 512,
  height: 512,
  steps: 30,
  cfgScale: 7,
  seed: -1
})

// 表单验证规则
const rules = {
  prompt: [
    { required: true, message: '请输入提示词', trigger: 'blur' },
    { min: 3, message: '提示词至少需要3个字符', trigger: 'blur' }
  ],
  modelName: [
    { required: true, message: '请选择模型', trigger: 'change' }
  ]
}

// 状态管理
const generating = ref(false)
const generationFormRef = ref<any>(null)
const generationResult = ref<Txt2ImgResponse | null>(null)
const models = ref<ModelConfig[]>([])
const loadingModels = ref(false)

// 状态映射
const statusTypeMap: Record<string, string> = {
  'pending': 'info',
  'processing': 'warning',
  'success': 'success',
  'failed': 'danger'
}

const statusTextMap: Record<string, string> = {
  'pending': '等待中',
  'processing': '处理中',
  'success': '成功',
  'failed': '失败'
}

// 检查服务状态
async function checkService() {
  checkingStatus.value = true
  try {
    const response = await checkServiceHealth()
    serviceStatus.value = response.code === 200 && response.data
    
    if (serviceStatus.value) {
      ElMessage.success('服务运行正常')
    } else {
      ElMessage.warning('服务未运行，请稍后重试')
    }
  } catch (error) {
    console.error('检查服务状态失败:', error)
    serviceStatus.value = false
    ElMessage.error('检查服务状态失败')
  } finally {
    checkingStatus.value = false
  }
}

// 加载模型
async function loadModels() {
  loadingModels.value = true
  try {
    const response = await getText2ImgModels()
    if (response.code === 200 && response.data) {
      models.value = response.data
      
      // 如果当前未选择模型且有可用模型，则选择默认模型
      if (!generationForm.modelName && models.value.length > 0) {
        // 查找默认模型
        const defaultModel = models.value.find((model: ModelConfig) => model.isDefault)
        if (defaultModel) {
          generationForm.modelName = defaultModel.modelName
          // 设置默认模型的其他参数
          setModelDefaults(defaultModel)
        } else {
          // 如果没有默认模型，使用第一个
          generationForm.modelName = models.value[0].modelName
          setModelDefaults(models.value[0])
        }
      }
    }
  } catch (error) {
    console.error('加载模型失败:', error)
    ElMessage.error('加载模型失败')
  } finally {
    loadingModels.value = false
  }
}

// 设置模型默认参数
function setModelDefaults(model: ModelConfig) {
  generationForm.steps = model.steps
  generationForm.cfgScale = model.cfgScale
  generationForm.width = model.defaultWidth || model.width || 512
  generationForm.height = model.defaultHeight || model.height || 512
}

// 使用模型配置
function useModelConfig(model: ModelConfig) {
  generationForm.modelName = model.modelName
  setModelDefaults(model)
  
  // 使用模型提供的默认提示词
  if (model.positivePrompt) {
    generationForm.prompt = model.positivePrompt
  }
  
  if (model.negativePrompt) {
    generationForm.negativePrompt = model.negativePrompt
  }
  
  // 滚动到表单位置
  document.querySelector('.generation-panel')?.scrollIntoView({ behavior: 'smooth' })
}

// 模型变更处理
function onModelChange(modelName: string) {
  const selectedModel = models.value.find((model: ModelConfig) => model.modelName === modelName)
  if (selectedModel) {
    setModelDefaults(selectedModel)
  }
}

// 设置图像尺寸
function setSize(width: number, height: number) {
  generationForm.width = width
  generationForm.height = height
}

// 提交生成表单
function submitForm() {
  generationFormRef.value.validate(async (valid: boolean) => {
    if (valid) {
      generating.value = true
      try {
        const response = await generateImage(generationForm)
        if (response.code === 200) {
          generationResult.value = response.data
          
          // 处理imageUrl
          if (!generationResult.value.imageUrl && generationResult.value.imageUrls) {
            const url = getImageUrlFromUrls(generationResult.value.imageUrls)
            if (url) {
              generationResult.value.imageUrl = url
            }
          }
          
          ElMessage.success('图像生成请求已提交')
          
          // 如果状态是pending或processing，开始轮询状态
          if (response.data.status === 'pending' || response.data.status === 'processing') {
            pollGenerationStatus(response.data.taskId)
          }
        } else {
          ElMessage.error(response.msg || '图像生成请求失败')
        }
      } catch (error) {
        console.error('图像生成错误:', error)
        ElMessage.error('图像生成请求失败')
      } finally {
        generating.value = false
      }
    }
  })
}

// 轮询生成状态
function pollGenerationStatus(taskId: string) {
  let attempts = 0
  const maxAttempts = 30 // 最多尝试30次，每次5秒
  
  const timer = setInterval(async () => {
    if (attempts >= maxAttempts) {
      clearInterval(timer)
      ElMessage.warning('生成任务超时，请在历史记录中查看结果')
      return
    }
    
    attempts++
    try {
      const response = await getRecordByTaskId(taskId)
      if (response.code === 200 && response.data) {
        const status = response.data.status
        
        // 处理imageUrl
        if (!response.data.imageUrl && response.data.imageUrls) {
          const url = getImageUrlFromUrls(response.data.imageUrls)
          if (url) {
            response.data.imageUrl = url
          }
        }
        
        // 更新当前结果
        generationResult.value = response.data
        
        // 如果已完成（成功或失败），停止轮询
        if (status === 'success' || status === 'failed') {
          clearInterval(timer)
          
          if (status === 'success') {
            ElMessage.success('图像生成成功')
          } else {
            ElMessage.error('图像生成失败: ' + (response.data.errorMessage || '未知错误'))
          }
        }
      } else {
        clearInterval(timer)
        ElMessage.error('获取生成状态失败')
      }
    } catch (error) {
      console.error('轮询状态错误:', error)
      clearInterval(timer)
    }
  }, 5000) // 每5秒检查一次
}

// 从imageUrls字符串中提取第一个URL
function getImageUrlFromUrls(imageUrls?: string | string[]): string | null {
  if (!imageUrls) return null
  
  // 如果imageUrls已经是数组，直接取第一个元素
  if (Array.isArray(imageUrls)) {
    return imageUrls.length > 0 ? imageUrls[0] : null
  }
  
  // 如果是字符串，尝试解析为JSON
  try {
    const urls = JSON.parse(imageUrls) as string[]
    return urls && urls.length > 0 ? urls[0] : null
  } catch (error) {
    console.error('解析图像URL错误:', error)
    return imageUrls || null // 如果无法解析，则返回原始字符串
  }
}

// 获取图像URL（支持两种格式）
function getImageUrl(record: Txt2ImgResponse | null): string | null {
  if (!record) return null
  
  if (record.imageUrl) {
    return record.imageUrl
  }
  
  return getImageUrlFromUrls(record.imageUrls)
}

// 下载生成的图像
function downloadImage() {
  const imageUrl = getImageUrl(generationResult.value)
  if (!imageUrl) return
  
  const link = document.createElement('a')
  link.href = imageUrl
  link.download = `image_${generationResult.value!.taskId}.png`
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

// 使用相同参数重新生成
function regenerateWithSameParams() {
  if (!generationResult.value) return
  
  // 使用当前结果的参数更新表单
  generationForm.prompt = generationResult.value.prompt
  generationForm.negativePrompt = generationResult.value.negativePrompt || ''
  generationForm.modelName = generationResult.value.modelName
  generationForm.width = generationResult.value.width
  generationForm.height = generationResult.value.height
  
  if (generationResult.value.steps) {
    generationForm.steps = generationResult.value.steps
  }
  
  if (generationResult.value.cfgScale) {
    generationForm.cfgScale = generationResult.value.cfgScale
  }
  
  // 生成新的随机种子或使用相同种子
  if (generationResult.value.seed !== undefined && generationResult.value.seed !== null) {
    generationForm.seed = generationResult.value.seed
  }
  
  // 提交表单
  submitForm()
}

// 格式化日期时间
function formatDateTime(timestamp: string | null) {
  if (!timestamp) return '-'
  const date = new Date(timestamp)
  return `${date.getFullYear()}-${padZero(date.getMonth() + 1)}-${padZero(date.getDate())} ${padZero(date.getHours())}:${padZero(date.getMinutes())}:${padZero(date.getSeconds())}`
}

function padZero(num: number) {
  return num.toString().padStart(2, '0')
}

// 生命周期钩子
onMounted(() => {
  checkService()
  loadModels()
})
</script>

<style scoped>
.text2img-container {
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.service-status {
  display: flex;
  align-items: center;
  gap: 8px;
}

.generation-panel, .preview-card {
  margin-bottom: 20px;
}

.preset-sizes {
  margin-top: 10px;
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.seed-options {
  margin-top: 8px;
  display: flex;
  gap: 10px;
}

.preview-container {
  min-height: 300px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.image-container {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.result-image {
  max-width: 100%;
  max-height: 500px;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.image-info {
  margin-top: 15px;
  width: 100%;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 10px;
}

.image-actions {
  margin-top: 20px;
  display: flex;
  gap: 10px;
}

.placeholder {
  text-align: center;
  color: #909399;
}

.empty-image-large {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 0;
  color: #909399;
}

.empty-image-large p {
  margin-top: 16px;
}

.error-container {
  width: 100%;
  max-width: 500px;
}

.error-message {
  margin-top: 15px;
  color: #F56C6C;
  white-space: pre-line;
}

.model-option {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .image-info {
    grid-template-columns: 1fr;
  }
  
  .image-actions {
    flex-direction: column;
    width: 100%;
  }
}

.full-width-section {
  width: 100%;
}
</style> 